/*
 * Copyright (C) 2009 Leandro de Oliveira Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.japa.repository.query;

import com.google.code.japa.annotation.*;
import com.google.code.japa.repository.*;

/**
 * Parameters to execute queries against the repository.
 * <p>Usually, defined using annotations.
 * 
 * @author Leandro Aparecido
 * @since 1.0
 * @see com.google.code.japa.annotation.RepositoryQuery
 * @see com.google.code.japa.repository.RepositoryAnnotationParameters
 */
@SuppressWarnings("unchecked")
public class RepositoryQueryParameters extends RepositoryAnnotationParameters {
	/**
	 * Indicates if the query should return the extent of the entity.
	 */
	private boolean extent;

	/**
	 * Type of the entity the query retrieves instances from.
	 */
	private Class type;
	
	/**
	 * Fetch strategy that must be used when retrieving entities of the extent.
	 */
	private FetchStrategy fetchStrategy;
	
	/**
	 * Fetch size for fetch strategies that support/require it.
	 */
	private int fetchSize;
	
	public boolean isExtent() {
		return extent;
	}

	public void setExtent(boolean extent) {
		this.extent = extent;
	}

	public Class getType() {
		return type;
	}
	
	public void setType(Class type) {
		this.type = type;
	}
	
	public FetchStrategy getFetchStrategy() {
		return fetchStrategy;
	}
	
	public void setFetchStrategy(FetchStrategy fetchStrategy) {
		this.fetchStrategy = fetchStrategy;
	}
	
	public int getFetchSize() {
		return fetchSize;
	}
	
	public void setFetchSize(int fetchSize) {
		this.fetchSize = fetchSize;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + (extent ? 1231 : 1237);
		result = prime * result + fetchSize;
		result = prime * result + ((fetchStrategy == null) ? 0 : fetchStrategy.hashCode());
		result = prime * result + ((type == null) ? 0 : (type.getCanonicalName() == null) ? 0 : type.getCanonicalName().hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (!super.equals(obj)) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		RepositoryQueryParameters other = (RepositoryQueryParameters) obj;
		if (extent != other.extent) {
			return false;
		}
		if (fetchSize != other.fetchSize) {
			return false;
		}
		if (fetchStrategy == null) {
			if (other.fetchStrategy != null) {
				return false;
			}
		} else if (!fetchStrategy.equals(other.fetchStrategy)) {
			return false;
		}
		if (type == null) {
			if (other.type != null) {
				return false;
			}
		} else if (type != other.type) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		return super.toString() + ";extent=" + extent + ";type=" + type;
	}
}
